#include <string.h>
#include "ota_mcu_upgrade.h"
#include "ota/ota_service.h"
#include "aos/hal/flash.h"
#include "ota_log.h"
#include "ota_import.h"
#include "ota_hal_os.h"

#if defined OTA_CONFIG_MCU_CAN
#include "canopen/canopen.h"
#include "canopen/canopen_od.h"
#endif

int ota_mcu_hal_init(void)
{
    int ret = 0;
    hal_flash_dis_secure(0, 0, 0);//disable flash protect
    hal_logic_partition_t part_info = {0};
    hal_flash_info_get(HAL_PARTITION_OTA_SUB, &part_info);
    unsigned int len = part_info.partition_length;
    unsigned int off = 0;
    unsigned int block_size = 0;
    while(len > 0) {
         block_size = (len > OTA_FLASH_BLOCK_SIZE)? OTA_FLASH_BLOCK_SIZE: len;
         ret = hal_flash_erase(HAL_PARTITION_OTA_SUB, off, block_size);
         if(ret < 0) {
             ret = OTA_INIT_FAIL;
         }
         off += block_size;
         len -= block_size;
         ota_msleep(10);
    }
    OTA_LOG_I("ota mcu init.\n");
    return ret;
}

int ota_mcu_hal_read(unsigned int *off, unsigned char *buf, unsigned int len)
{
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(buf == NULL || len <= 0) {
        return ret;
    }
    ret = hal_flash_read(HAL_PARTITION_OTA_SUB, off, buf, len);
    return ret;
}

int ota_mcu_hal_write(unsigned int* off, unsigned char* buf, unsigned int len)
{
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(buf == NULL || len <= 0) {
        return ret;
    }
    ret = hal_flash_write(HAL_PARTITION_OTA_SUB, off, buf, len);
    return ret;
}

int ota_mcu_hal_version(void *device, char *version)
{
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(version == NULL) {
        OTA_LOG_E("mcu version err.");
        return ret;
    }
#if defined OTA_CONFIG_MCU_CAN
    ret = co_sdo_read_od(device, CO_SW_VERSION_INDEX, CO_SW_VERSION_SUB_INDEX, version, OTA_VER_LEN);
    OTA_LOG_I("MCU version get:%s ret:%d ", version, ret);
#endif
    return ret;
}

int ota_mcu_hal_recv(void *device, unsigned char *buf, unsigned int len)
{
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(buf == NULL || len <= 0) {
        return ret;
    }
#if defined OTA_CONFIG_MCU_CAN
    ret = co_upgrade_recv(device, len, buf, OTA_MCU_TIMEOUT);
    if (ret < 0) {
        OTA_LOG_I("recv data err:%d\n", ret);
        return OTA_MCU_UPGRADE_FAIL;
    }
    OTA_LOG_I("mcu recv:0x%02x \n", buf[0]);
#elif defined ATHOST_MQTT
    ret = atcmd_read((unsigned char*)buf, len);
#endif
    return ret;
}

int ota_mcu_hal_send(void *device, unsigned char* buf, unsigned int len)
{
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(buf == NULL || len <= 0) {
        return ret;
    }
#if defined OTA_CONFIG_MCU_CAN
    ret = co_sdo_write_od(device, CO_UPGRADE_INDEX, CO_UPGRADE_SUB_INDEX, buf, len);
    if (ret < 0) {
        OTA_LOG_I("send data err:%d\n", ret);
        return OTA_MCU_UPGRADE_FAIL;
    }
    OTA_LOG_I("mcu send cmd:0x%02x \n", buf[4]);
#elif defined ATHOST_MQTT
    ret = atcmd_write(NULL, (unsigned char *)buf, 0, len, NULL);
#endif
    return ret;
}

int ota_mcu_upgrade_start(unsigned int size, char* ver, char* md5)
{
    unsigned int img_size = 0;
    int ret = OTA_MCU_UPGRADE_FAIL;
    if(size <= 0 || ver == NULL || strlen(ver) >= 64) {
        OTA_LOG_I("mcu ota version.\n");
        return ret;
    }
    hal_logic_partition_t part_info = {0};
    hal_flash_info_get(HAL_PARTITION_OTA_TEMP, &part_info);

    if(size > part_info.partition_length) {
        img_size = size - part_info.partition_length;
    } else {
        img_size = size;
    }
    OTA_LOG_I("mcu ota start: img size:%d  ver:%s \n", img_size, ver);
#if defined OTA_CONFIG_MCU_CAN
    ret = ota_mcu_can_upgrade(img_size, ver, md5);
#elif defined OTA_CONFIG_MCU_YMODEM
    ret = ota_mcu_ymodem_upgrade(img_size, ver, md5);
#endif
    return ret;
}
